package com.lagou.edu.factory;

import java.lang.reflect.Field;
import java.util.*;

/**
 * @author 应癫
 *
 * 工厂类，生产对象（使用反射技术）
 */
public abstract class AbstractBeanFactory implements BeanFactory{

    private static Map<String,Object> singletonObjects = new HashMap<>();  //一级bean容器

    private static List<EarlySingletonObject> earlySingletonObjects = new ArrayList<>();  // 二级存储对象

    public void init() throws Exception{

        createSingleTonObjects();//实例化bean至容器

        clearEarlySingletonObjects();//处理未初始化完成的bean

        replaceProxyObjects();//处理需要生成代理对象的bean

        System.out.println(singletonObjects);
    }

    protected abstract void replaceProxyObjects();

    protected abstract void createSingleTonObjects() throws Exception;

    protected abstract void clearEarlySingletonObjects() throws Exception;

    public void setBean(String id, Object o) {
        if (!Character.isLowerCase(id.charAt(0))){
            id = (new StringBuilder()).append(Character.toLowerCase(id.charAt(0))).append(id.substring(1)).toString();
        }
        singletonObjects.put(id, o);
    }

    public Object getBean(String id) {
        return singletonObjects.get(id);
    }

    // 对外提供获取实例对象的接口（根据类型获取）
    public Object getBean(Class clazz) {
        Set<Map.Entry<String, Object>> entrySet = singletonObjects.entrySet();
        for (Map.Entry entry : entrySet){
            if(entry.getValue().getClass().equals(clazz)){
                return entry.getValue();
            }
        }
        return null;
    }

    public List<EarlySingletonObject> getEarlySingletonObjects() {
        return earlySingletonObjects;
    }

    public static Map<String, Object> getSingletonObjects() {
        return singletonObjects;
    }

    public void setEarlySingletonObjects(String id, Object o, List<Field> fields) {
        EarlySingletonObject earlySingletonObject = new EarlySingletonObject();
        earlySingletonObject.setId(id);
        earlySingletonObject.setObject(o);
        earlySingletonObject.setFields(fields);
        earlySingletonObjects.add(earlySingletonObject);
    }

}
